package MyRemoteSorter;
import java.util.ArrayList;
import java.util.Observer;
import java.util.Observable;

public class ListJoiner implements Observer 
{
	private static int lastThreadNumber = 0;
	private static  int runningThreads = 0;
	Comparable[] sortedResult;
	public ListJoiner()
	{
	}
	
	public ListJoiner getListJoiner()
	{
		return this;
	}
	
	public int getNextThreadNumber()
	{
		verhoogThreadNumber();
		return lastThreadNumber;
	}
	
	private void verhoogThreadNumber()
	{
		lastThreadNumber++;
		runningThreads=lastThreadNumber;
	}
	
	private synchronized void join(Comparable[] part)
	{
		if(sortedResult == null)
		{
			sortedResult = part;
		}
		else
		{
			sortedResult = quickMerge(part);
		}	
	}
	private Comparable[] smartMerge()
	{
		//ToDo: implement smartMerge with presorted list and threadnumbers
		return new Comparable[0];
	}
	
	private Comparable[] quickMerge(Comparable[] part)
	{
		ArrayList<Comparable<Comparable>> tmpList = new ArrayList<Comparable<Comparable>>(sortedResult.length+part.length);
		fillArrayList(tmpList);
		
		fillListWithArrayAndBubbleSortList(part, tmpList);
		return tmpList.toArray(new Comparable[0]);
	}

	private void fillListWithArrayAndBubbleSortList(Comparable[] part,
			ArrayList<Comparable<Comparable>> tmpList) {
		for(Comparable newObject: part)
		{
			int index = 0;
			while(index<tmpList.size())
			{
				if(index == tmpList.size()-1 && newObject.compareTo(tmpList.get(index))>0)
				{
					tmpList.add( newObject);
					break;
				}
				else if(index == tmpList.size()-1 && newObject.compareTo(tmpList.get(index))<=0)
				{
					tmpList.add(index,newObject);
					break;
				}
				else if(newObject.compareTo(tmpList.get(index)) <1)
				{
					tmpList.add(index,newObject);
					break;
				}
				else if(newObject.compareTo(tmpList.get(index)) >1 && newObject.compareTo(tmpList.get(index+1))<=0)
				{
					tmpList.add(index,newObject);
					break;
				}
				else
				{
					index++;
				}	
			}
		}
	}

	private void fillArrayList(ArrayList<Comparable<Comparable>> tmpList) {
		for(Comparable<Comparable> comparableObject: sortedResult)
		{
			tmpList.add(comparableObject);
		}
	}
	
	public void printJoinedList()
	{
		System.out.println("EINDRESULTAAT:");
		for (int i = 0; i < sortedResult.length; i++) {
			System.out.println(i +" "+sortedResult[i]);
		}
		System.out.println(System.currentTimeMillis());
		
	}
	
	public void update(Observable obs, Object o)
	{
		if(obs instanceof SorterThread && o instanceof Comparable[])
		{
			SorterThread thread = (SorterThread) obs;
			Comparable[] sorterDeel = (Comparable[]) o;
			join(sorterDeel);
			runningThreads--;
			if(runningThreads == 0)
			{
				printJoinedList();
			}
		}	
	}

}
